import gradio as gr
import os
import sys

# 添加项目根目录到 Python 路径
script_dir = os.path.dirname(os.path.abspath(__file__))
sys.path.insert(0, script_dir)

# 导入必要的模块
from dwspark.config import Config
from dwspark.models import VoiceSynthesis
from loguru import logger

# 默认的API凭证
DEFAULT_APP_ID = "62381f24"
DEFAULT_API_KEY = "c6ca5f21d2abf73dfb163b2e623b71ae"
DEFAULT_API_SECRET = "OTEwMzQzOTA2YmQ4ZDM4NmU5NzBmMjFm"

def synthesize_voice(audio_file, text, app_id, api_key, api_secret):
    """
    使用上传的音频文件和输入的文本进行语音合成
    
    Parameters:
    -----------
    audio_file : tempfile._TemporaryFileWrapper
        上传的训练音频文件
    text : str
        要合成的文本
    app_id, api_key, api_secret : str
        API 凭证
    
    Returns:
    --------
    str or None
        合成的音频文件路径或错误信息
    """
    if not audio_file or audio_file == "":
        return None, "请上传音频文件"
    
    if not text:
        return None, "请输入要合成的文本"
    
    # 使用提供的或默认的 API 凭证
    app_id = app_id if app_id else DEFAULT_APP_ID
    api_key = api_key if api_key else DEFAULT_API_KEY
    api_secret = api_secret if api_secret else DEFAULT_API_SECRET
    
    try:
        # 初始化配置和模型
        conf = Config(appid=app_id, apikey=api_key, apisecret=api_secret)
        model = VoiceSynthesis(conf, stream=False)
        
        # 准备输出目录 - 使用时间戳更容易区分不同的输出文件
        import time
        timestamp = int(time.time())
        output_dir = os.path.join(script_dir, "synthesized_outputs")
        os.makedirs(output_dir, exist_ok=True)
        output_path = os.path.join(output_dir, f"output_{timestamp}.mp3")
        
        # 确保音频文件存在
        if not os.path.exists(audio_file):
            return None, f"错误: 找不到音频文件 {audio_file}"
        
        # 设置参数并生成
        params = {
            'text': text,
            'model_name': "gradio_model",
            'audio_path': audio_file,  # 音频文件路径
            # 'force_train': True,           # 强制训练
            'output_path': output_path,
            'voice_model_config': 'voice_models.json'
        }
        
        # 生成合成语音
        result = model.generate(params)
        print(result)
        # 检查结果
        if result and os.path.exists(result):
            return result, f"合成成功: {os.path.basename(result)}"
        else:
            return None, "合成失败，请检查日志"
    
    except Exception as e:
        import traceback
        logger.error(f"合成过程中发生错误: {str(e)}")
        logger.error(traceback.format_exc())
        return None, f"错误: {str(e)}"

# 创建 Gradio 界面
with gr.Blocks(title="简易语音合成") as demo:
    gr.Markdown("## 简易语音合成界面")
    
    with gr.Row():
        with gr.Column():
            gr.Markdown("### 1. 上传您的训练音频")
            audio_input = gr.Audio(type="filepath", label="训练音频")
            
            gr.Markdown("### 2. 输入要合成的文本")
            text_input = gr.Textbox(label="合成文本", placeholder="请输入要合成的文本...", lines=3)
            
            with gr.Accordion("API 凭证 (可选)", open=False):
                app_id_input = gr.Textbox(label="APPID", value=DEFAULT_APP_ID, placeholder="请输入APPID")
                api_key_input = gr.Textbox(label="APIKey", value=DEFAULT_API_KEY, placeholder="请输入APIKey")
                api_secret_input = gr.Textbox(label="APISecret", value=DEFAULT_API_SECRET, placeholder="请输入APISecret")
            
            synthesize_btn = gr.Button("开始合成", variant="primary")
        
        with gr.Column():
            gr.Markdown("### 3. 合成结果")
            output_audio = gr.Audio(label="合成的语音")
            output_message = gr.Textbox(label="状态信息", lines=2)
    
    # 设置点击事件
    synthesize_btn.click(
        fn=synthesize_voice,
        inputs=[audio_input, text_input, app_id_input, api_key_input, api_secret_input],
        outputs=[output_audio, output_message]
    )

if __name__ == "__main__":
    print("正在启动简易语音合成界面...")
    demo.launch()
